<template>
  <div class="w-full h-full bg-gray-200 pb-10">
    <div style="width: fit-content; background: pink">宽度适应内容</div>
    <div class="t_boxs flex items-center justify-center font-bold">
      <div>文字差--文字透明，背景固定 这个固定位置是死的</div>
    </div>
    <label>
      {{ numStr }}
    </label>
    <input
      :value="num"
      placeholder="数字转中文"
      type="number"
      @change="e => (num = Number((e.target as HTMLInputElement).value))"
    />
    <div class="btn cursor-pointer">
      高度自动过渡
      <div class="detail">
        <div class="content">
          <div class="inner">
            charts 数组就包含了零到九对应的字符串。其中，charts[0] 对应
            "零"，charts[1] 对应 "一"，以此类推
          </div>
        </div>
      </div>
    </div>
    <ul>
      <li>旋涡数组</li>
      <li v-for="(i, idx) in vortexList" :key="idx">
        {{ i }}
      </li>
    </ul>
    <div class="banner flex justify-center items-center">
      <div class="tit">css混合模式mix-blend-mode</div>
    </div>
    <h3>蜂巢布局</h3>
    <div class="box">
      <div class="line">
        <div class="item_l" v-for="(i, idx) in 10" :key="idx">
          <img
            :src="'https://picsum.photos/200/300?random=' + Math.random() * 10"
          />
        </div>
      </div>
      <!--      偶数个就需要多布局一个  11个-->
      <div class="line">
        <div class="item_l" v-for="(i, idx) in 11" :key="idx">
          <img
            :src="'https://picsum.photos/200/300?random=' + Math.random() * 10"
          />
        </div>
      </div>
      <div class="line">
        <div class="item_l" v-for="(i, idx) in 10" :key="idx">
          <img
            :src="'https://picsum.photos/200/300?random=' + Math.random() * 10"
          />
        </div>
      </div>
    </div>
    <h3>拼音</h3>
    <div class="flex flex-col">
      <div class="flex">
        <!--        布局应该是一个box包括拼音和中文 就这样了现在-->
        <div class="text-center" v-for="(i, idx) in result" :key="idx">
          {{ i }}
        </div>
      </div>
      <div>中 国</div>
    </div>

    <h3>判断鼠标进入方向</h3>
    <div id="wrap">
      <span class="text">MOVE</span>
      <div class="cover" />
    </div>
    <h3>鼠标移动的高亮边框效果</h3>
    <div
      class="wraps relative w-[200px] h-[200px] flex items-center justify-center bg-black bg-opacity-10 rounded-[8px] overflow-hidden"
    >
      <div class="inner absolute flex items-center justify-center">
        wafpngpuoia
      </div>
    </div>
    <div>
      如何跳转一个页面打开后，第二次跳转过去
      参数发生变化，但是不是打开的新的页面 ： 标签页通信
    </div>
    <div>新单位：vmin:取视口最短边 ; vmax:取视口最长边</div>
    <h3>黑白小球交替loading效果 目标：复习scss</h3>
    <div class="loading">
      <div class="dot" v-for="i in 36" :key="i" />
    </div>

    <div class="bg-black contrast-30 flex items-center justify-center">
      <div class="expend">web developer</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue-demi";
import { computed, nextTick } from "vue";
import { pinyin } from "pinyin-pro";

const num = ref(456700);
function toChineseNumber(num) {
  //如果要转成大写 在搞一个映射就行
  const charts = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
  const units = ["", "十", "百", "千"];
  const bigUnits = ["", "万", "亿"];
  let result = "";
  const numStr = num
    .toString()
    .replace(/(?=(\d{4})+$)/g, ",")
    .split(",")
    .filter(Boolean); // 过滤空的字符串 filter(Boolean)
  // console.log(numStr)
  const _transform = n => {
    //转化四位字符串
    if (n === "0000") return charts[0];
    let result = "";
    for (let i = 0; i < n.length; i++) {
      const c = charts[+n[i]]; //+ 字符转数字  拿到汉字数字
      let u = units[n.length - 1 - i];
      if (c === charts[0]) {
        u = "";
      }
      result += c + u;
    }
    result = result.replace(/零{2,,}/g, "零").replace(/零+$/g, ""); //中间连续的零换成一个，末尾的零去掉 读音才对
    return result;
  };
  numStr.forEach((i, idx) => {
    const c = _transform(i);
    let u = bigUnits[numStr.length - 1 - idx];
    if (c === charts[0]) {
      u = "";
    }
    result += c + u;
  });
  return result;
}
const numStr = computed(() => toChineseNumber(num.value));
nextTick(() => {
  // 高度自动过度 第四种 filp
  const btn = document.querySelector(".btn") as HTMLElement;
  const detail = document.querySelector(".detail") as HTMLElement;
  btn.onmouseenter = function () {
    detail.style.height = "auto";
    const { height } = detail.getBoundingClientRect();
    detail.style.height = String(0);
    detail.style.overflow = "hidden";
    detail.style.transition = ".3s";
    detail.offsetHeight; // 类似 nextTick
    detail.style.height = height + "px";
  };
  btn.onmouseleave = function () {
    detail.style.height = String(0);
    detail.style.transition = ".3s";
    detail.style.overflow = "hidden";
  };
});

// 旋涡二维数组
const vortex = (n, m) => {
  /**
   * 123
   * 894
   * 765
   */
  const nums = new Array(n).fill(0).map(() => new Array(m).fill(0));
  let i = 0,
    j = 0,
    count = 1; //i==row j == column
  let stepI = 0,
    stepJ = 1; //i的变化 j的变化 0不变 -1往左边走  1 往右边走
  // eslint-disable-next-line no-constant-condition
  while (true) {
    nums[i][j] = count++;
    if (!nums[i + stepI] || nums[i + stepI][j + stepJ] !== 0) {
      //是否需要转弯
      if (stepI === 0) {
        //行变列
        stepI = stepJ;
        stepJ = 0;
      } else {
        //列变行
        stepJ = -stepI;
        stepI = 0;
      }
      if (!nums[i + stepI] || nums[i + stepI][j + stepJ] !== 0) {
        break;
      }
    }
    i += stepI;
    j += stepJ;
  }
  return nums;
};
const vortexList = vortex(3, 3);
// 蜂巢布局
// 获取所有元素
nextTick(() => {
  // 获取所有元素
  const items = document.getElementsByClassName("item_l");
  // 存储当前选中的元素
  let selectedElement = null;
  // 存储当前选中元素的标识
  // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars
  let selectedIndex = -1;
  // console.log(items,items.length)
  // 遍历每个元素
  Array.from(items).forEach((item, index) => {
    // 鼠标移入事件处理函数
    item.addEventListener("mouseover", () => {
      // 重置之前选中元素的样式
      if (selectedElement) {
        selectedElement.style.transform = "scale(1)";
      }

      // 设置当前选中的元素和标识
      selectedElement = item;
      selectedIndex = index;
      // 设置当前选中元素放大
      selectedElement.style.transform = "scale(1.2)";

      // 获取上方元素

      // 获取左侧元素

      // 获取右侧元素

      // 获取下方元素
    });

    // 鼠标移出事件处理函数
    item.addEventListener("mouseout", () => {
      // 重置元素的样式
      (item as HTMLElement).style.transform = "scale(1)";
    });
  });
});
// 拼音
const result = pinyin("中国", { type: "array" });
// 判断鼠标进入方向  --角度判断
nextTick(() => {
  // 获取容器
  let wrap = document.getElementById("wrap");

  // 获取遮罩层
  let cover = document.querySelector(".cover");
  let text = document.querySelector(".text");
  // 获取容器的相关属性
  console.log(wrap.getBoundingClientRect());
  let {
    width: w,
    height: h,
    left: offsetLeft,
    top: offsetTop
  } = wrap.getBoundingClientRect();
  //   定义一个方向数组
  let dirName = ["top", "right", "bottom", "left"];
  //   监听鼠标进入容器时
  wrap.addEventListener("mouseenter", e => {
    // console.log(e.pageX, offsetLeft, w);
    let x = (e.pageX - offsetLeft - w / 2) * (w > h ? h / w : 1);
    let y = (e.pageY - offsetTop - h / 2) * (h > w ? w / h : 1);
    // console.log(x);
    // 用来获取移入的方位  核心
    // 通过Math.atan2 计算角度 https://www.jianshu.com/p/9817e267925a
    // (Math.atan2(y, x) * (180 / Math.PI)计算弧度
    // + 180：将角度值加上 180，目的是将方向的范围从 -180 到 180 转换为 0 到 360
    // 将角度值除以 90，将范围缩小到 0 到 4
    // + 3：将结果加上 3，从而将范围转换为 3 到 7。
    // % 4：对结果取模 4，使得结果的范围在 0 到 3 之间。
    let direction =
      Math.round((Math.atan2(y, x) * (180 / Math.PI) + 180) / 90 + 3) % 4;
    let dirText = dirName[direction];
    text.innerHTML = dirText + " Enter"; //文字修改
    switch (dirText) {
      case "top":
        cover.setAttribute("class", "cover topEnter");
        break;
      case "right":
        cover.setAttribute("class", "cover rightEnter");
        break;
      case "bottom":
        cover.setAttribute("class", "cover bottomEnter");
        break;
      case "left":
        cover.setAttribute("class", "cover leftEnter");
        break;
      default:
        break;
    }
  });
  // 监听鼠标移出容器时
  wrap.addEventListener("mouseleave", function (e) {
    let x = (e.pageX - offsetLeft - w / 2) * (w > h ? h / w : 1);
    let y = (e.pageY - offsetTop - h / 2) * (h > w ? w / h : 1);
    // 用来获取移入的方位
    // 通过Math.atan2 计算角度 https://www.jianshu.com/p/9817e267925a
    let direction =
      Math.round((Math.atan2(y, x) * (180 / Math.PI) + 180) / 90 + 3) % 4;
    let dirText = dirName[direction];
    text.innerHTML = dirText + " Leave"; //文字修改
    // 通过移入方位，添加移出动画class
    switch (dirText) {
      case "top":
        cover.setAttribute("class", "cover topLeave");
        break;
      case "right":
        cover.setAttribute("class", "cover rightLeave");
        break;
      case "bottom":
        cover.setAttribute("class", "cover bottomLeave");
        break;
      case "left":
        cover.setAttribute("class", "cover leftLeave");
        break;
      default:
        break;
    }
  });
});
// 鼠标移动高亮边框效果
nextTick(() => {
  let wraps = document.querySelector(".wraps");
  let inner = document.querySelector(".inner");
  wraps.onmousemove = function (e) {
    const rect = inner.getBoundingClientRect();
    const x = e.clientX - Math.abs(rect.left) + rect.width / 2;
    const y = e.clientY - Math.abs(rect.top) + rect.height / 2;
    wraps.style.setProperty("--x", `${x}px`);
    wraps.style.setProperty("--y", `${y}px`);
  };
});
// 标签页通信
nextTick(() => {
  //   代码
  // const channel = new BroadcastChannel("名字"); //同源
  // channel.postMessage("懂了"); //另外一边监听如下
  // channel.addEventListener('message',(e)=>{}) //有点$bus那味了 还可以结合localeStorage
  //   页面打开用 window.open('./xxx.html?参数','名字')
});

defineOptions({
  name: "OneDemo"
});
</script>

<style scoped lang="scss">
.btn {
  width: fit-content;
  height: 30px;
  background: pink;
  position: relative;
  .detail {
    position: absolute;
    border: 1px solid red;
    top: 30px;
    background: blue;
  }
  //第一种做法
  //.content {
  //  max-height: 0;
  //  transition: 0.5s;
  //  overflow: hidden;
  //}
  //&:hover .content {
  //  max-height: 1000px; //传统做法 给一个很高的高度 但是过渡时间有问题
  //}
  //  第二种做法  接近完美  一开始文字由压缩然后展开
  //  .detail {
  //    transform-origin:center top ; //中间开始展开
  //    transform: scaleY(0);
  //    transition: 0.5s;
  //  }
  //  &:hover .detail {
  //    transform: scaleY(1);
  //  }
  //  第三种 用网格布局的方式来做  --这种先不管了 原理是先0再1
  //  .detail {
  //    display:grid;
  //    grid-template-rows: 0fr;
  //    transition: 0.5s;
  //    border: 10px solid red;
  //  }
  //&:hover .detail {
  //  grid-template-rows: 1fr;
  //}
}
/**
  混合模式 色差混合
   */
.banner {
  background: linear-gradient(45deg, #000 50%, #fff 50%);
  .tit {
    color: #fff;
    font-size: 1em;
    transition: 0.5s;
    mix-blend-mode: difference; //混合模式 色差混合
  }
  &:hover .tit {
    transform: translateX(-100px);
  }
}
/**
  蜂巢布局
   */
$n: 10;
$size: calc(100vw / $n);
.box {
  .line {
    display: flex;
    margin-top: calc($size/ 6);
    &:nth-child(even) {
      transform: translateX(- calc($size / 2));
    }
    .item_l {
      width: $size;
      height: $size;
      background: #000;
      cursor: pointer;
      //有生成器
      clip-path: polygon(51% 10%, 92% 25%, 91% 75%, 50% 95%, 6% 76%, 6% 26%);
      //  不压缩
      flex-shrink: 0;
    }
  }
}
/**
文字差
 */
.t_boxs {
  position: relative;
  width: 200px;
  height: 100px;
  margin-top: 40px;
  text-align: center;
  background-image: linear-gradient(to bottom, #fe4e00 50%, lightblue 50%);
  background-position: 100% center;
  background-size: 200px 100px;
  background-attachment: fixed; //核心
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}
/**
鼠标进入方向判断
 */
#wrap {
  width: 200px;
  height: 200px;
  background: rgb(109, 47, 255);
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  position: relative;
  overflow: hidden;

  .text {
    position: relative;
    z-index: 5;
  }

  .cover {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 1;
    background: rgba(0, 0, 0, 0.397);
    opacity: 0;
    pointer-events: none;

    &.topEnter {
      opacity: 1;
      animation: topEnter 0.3s ease both 1;
    }

    &.rightEnter {
      opacity: 1;
      animation: rightEnter 0.3s ease both 1;
    }

    &.bottomEnter {
      opacity: 1;
      animation: bottomEnter 0.3s ease both 1;
    }

    &.leftEnter {
      opacity: 1;
      animation: leftEnter 0.3s ease both 1;
    }

    &.topLeave {
      opacity: 1;
      animation: topLeave 0.3s ease both 1;
    }

    &.rightLeave {
      opacity: 1;
      animation: rightLeave 0.3s ease both 1;
    }

    &.bottomLeave {
      opacity: 1;
      animation: bottomLeave 0.3s ease both 1;
    }

    &.leftLeave {
      opacity: 1;
      animation: leftLeave 0.3s ease both 1;
    }
  }
}

@keyframes topEnter {
  0% {
    transform: translateY(-100%);
  }

  100% {
    transform: translateY(0);
  }
}

@keyframes rightEnter {
  0% {
    transform: translateX(100%);
  }

  100% {
    transform: translateX(0);
  }
}

@keyframes bottomEnter {
  0% {
    transform: translateY(100%);
  }

  100% {
    transform: translateY(0);
  }
}

@keyframes leftEnter {
  0% {
    transform: translateX(-100%);
  }

  100% {
    transform: translateX(0);
  }
}

@keyframes topLeave {
  0% {
    transform: translateY(0);
  }

  100% {
    transform: translateY(-100%);
  }
}

@keyframes rightLeave {
  0% {
    transform: translateX(0);
  }

  100% {
    transform: translateX(100%);
  }
}

@keyframes bottomLeave {
  0% {
    transform: translateY(0);
  }

  100% {
    transform: translateY(100%);
  }
}

@keyframes leftLeave {
  0% {
    transform: translateX(0);
  }

  100% {
    transform: translateX(-100%);
  }
}

/**
鼠标移动的高亮边框效果
 */
.wraps {
  //第一层
  &::before {
    //第二层 移动的也是这层  整个模块移动transform
    content: "";
    position: absolute;
    z-index: 2; //注意点
    inset: 0;
    left: 0;
    top: 0;
    border-radius: inherit;
    //背景为黑色才会更加明显
    //background: radial-gradient(
    //  closest-side circle,
    //  rgba(255, 149, 0, 1) 0%,
    //  transparent
    //);
    background: red;
    transform: translate(var(--x, -1000px), var(--y, -1000px));
  }
  .inner {
    //第三层
    background: black;
    inset: 2px; //间隙 边框 可以通过这个
    z-index: 3; //注意点
  }
}
/**
循环小球
 */
$ballSize: 10px; //小球尺寸
$containerSize: 150px; //容器尺寸
$n: 36; //小球个数
$pDeg: calc(360deg / $n); //每个小球角度
$duration: 2s;
.loading {
  width: $containerSize;
  height: $containerSize;
  //border: 1px solid #fff;
  margin: 50px auto;
  position: relative;
  border-radius: 50%;
  .dot {
    position: absolute;
    left: 50%;
    top: 0;
    width: $ballSize;
    height: $ballSize;
    margin-left: calc(-1 * $ballSize / 2);
    margin-top: calc(-1 * $ballSize / 2);
    //background: #f40;
    transform-origin: center calc($containerSize / 2) + calc($ballSize / 2); // 旋转中心 原本是dot中心，现在取圆中心
    //甚至3d
    transform-style: preserve-3d;
    @for $i from 1 through $n {
      &:nth-child(#{$i}) {
        transform: rotate($pDeg * ($i - 1)); //展开变成小圆圈
        &::after,
        &::before {
          animation-delay: calc(
            -1 * $duration / $n * ($i - 1) * 6
          ); //动画延迟交替  技巧负数延迟时间：表示过去都实现了 来计算当前，就是不会从0开始
        }
      }
    }
    &::after,
    &::before {
      content: "";
      position: absolute;
      left: 0;
      top: 0;
      width: $ballSize;
      height: $ballSize;
      border-radius: 50%;
    }
    &::before {
      background: #000;
      top: -100%;
      animation: rotate_black $duration infinite;
      @keyframes rotate_black {
        //近小远大
        0% {
          animation-timing-function: ease-in; //运动曲线
        }
        25% {
          transform: translate3d(0, 100%, $ballSize);
          animation-timing-function: ease-out;
        }
        50% {
          transform: translate3d(0, 200%, 0);
          animation-timing-function: ease-in;
        }
        75% {
          transform: translate3d(0, 100%, -$ballSize);
          animation-timing-function: ease-out;
        }
      }
    }
    &::after {
      background: #fff;
      top: 100%;
      animation: rotate_white $duration infinite;
      @keyframes rotate_white {
        //近小远大
        0% {
          animation-timing-function: ease-in; //运动曲线
        }
        25% {
          transform: translate3d(0, -100%, -$ballSize);
          animation-timing-function: ease-out;
        }
        50% {
          transform: translate3d(0, -200%, 0);
          animation-timing-function: ease-in;
        }
        75% {
          transform: translate3d(0, -100%, $ballSize);
          animation-timing-function: ease-out;
        }
      }
    }
  }
}
/**
文字展开
 */
.expend {
  font-size: 40px;
  color: #0bdcb7;
  animation: show_up 3s forwards;
}
@keyframes show_up {
  from {
    letter-spacing: -50px; //就是间距
    filter: blur(10px);
  }
  to {
    letter-spacing: 10px;
    filter: blur(0px);
  }
}
</style>
